package UMC.Web.Activities;

import UMC.Data.Database;
import UMC.Data.Provider;
import UMC.Data.ProviderConfiguration;
import UMC.Data.Sql.DbProvider;
import UMC.Data.Sql.Initializer;
import UMC.Data.Utility;
import UMC.Web.*;

import java.io.File;
import java.util.*;

@Apiumc(model = "System", cmd = "Setup", desc = "UMC安装器", auth = WebAuthType.all)
public class SystemSetupActivity extends WebActivity {
    @Override
    public void processActivity(WebRequest request, WebResponse response) {
        String name = this.asyncDialog("Name", g -> {
            UISheetDialog fm = new UISheetDialog();
            fm.title("选择安装组件");

            for (Initializer v : Initializer.initializers()) {

                fm.put(new UIClick(request, g, v.name()).text(v.caption()));// .init(request.model(), request.cmd()));
            }
            return fm;
        });
        switch (name) {
            case "Command":
                WebMeta Command = this.asyncDialog(g -> {
                    UIFormDialog fm = new UIFormDialog();
                    fm.title("调试指令");

                    fm.addText("模块", "Model", "").placeholder("触发的模块");
                    fm.addText("指令", "Command", "").placeholder("触发的指令");
                    fm.addText("参数", "Send", "").notRequired().placeholder("触发的参数");
                    fm.submit("执行指令", "System.Setup");
                    fm.add(UICell.UI('\uf1b3', "扫描模块", "从新加载模块类型",
                            new UIClick(request.model(), request.cmd(), "Scanning")));

                    return fm;
                }, "Command");
                String send = Command.get("Send");
                if (Utility.isEmpty(send)) {
                    this.context().send(new UIClick(Command.get("Model"), Command.get("Command")), true);

                } else {
                    this.context().send(new UIClick(Command.get("Model"), Command.get("Command"), send), true);

                }
                break;
            case "Scanning":
                WebMeta cls = this.asyncDialog(r -> {

                    UIFormDialog formDialog = new UIFormDialog();
                    formDialog.title("加载类型");
                    formDialog.addText("类型", "Type", "").notRequired();
                    formDialog.submit("确认", "System.Setup");
                    return formDialog;
                }, "Class");
                if (Utility.isEmpty(cls.get("Type")) == false) {
                    try {
                        Class.forName(cls.get("Type"));
                    } catch (ClassNotFoundException e) {
                        this.prompt(e.getMessage());
                        // e.printStackTrace();
                    }
                }

                WebServlet.scanning();
                this.prompt("已从新扫描类型", false);

                this.context().send("System.Setup", true);
                break;
            case "Mapping":

                ProviderConfiguration setup = Utility.isNull(ProviderConfiguration.configuration("setup"),
                        new ProviderConfiguration());

                List<WebMeta> list = new LinkedList<>();
                for (Initializer initer3 : Initializer.initializers()) {

                    Provider provider = setup.get(initer3.name());
                    WebMeta meta = new WebMeta("name", initer3.name(), "text", initer3.caption());
                    if (provider != null && !Utility.isEmpty(provider.get("setup"))) {
                        meta.put("setup", true);
                    }
                    list.add(meta);
                }
                response.redirect(new WebMeta().put("component", list).put("data", WebServlet.mapping()));
                break;
            default:
                break;
        }

        ProviderConfiguration setup = Utility.isNull(ProviderConfiguration.configuration("setup"),
                new ProviderConfiguration());

        Initializer initer = Arrays.stream(Initializer.initializers()).filter(r -> name.equals(r.name())).findFirst()
                .orElse(null);
        if (initer == null) {
            this.prompt("无此业务组件");
        }

        if (!request.isMaster()) {
            if (setup.size() > 0) {
                this.prompt("只有管理员才能检测升级");
            }
        }
        ProviderConfiguration database = Utility.isNull(ProviderConfiguration.configuration("database"),
                new ProviderConfiguration());
        if (!Utility.isEmpty(initer.providerName()) && !database.containsKey(initer.providerName())) {
            String type = this.asyncDialog("type", g -> {
                UISheetDialog fm = new UISheetDialog();
                fm.title("安装数据库");
                fm.put(new UIClick(request, g, "SQLite").text("SQLite数据库"))
                        .put(new UIClick(request, g, "MySql").text("MySql数据库"))
                        .put(new UIClick(request, g, "Oracle").text("Oracle数据库"))
                        .put(new UIClick(request, g, "MSSQL").text("SQL Server数据库"));

                return fm;
            });
            WebMeta Settings = this.asyncDialog(g -> {
                UIFormDialog fm = new UIFormDialog();
                fm.title("选择数据库");

                fm.addText("服务地址", "Server", "");
                fm.addText("用户名", "User", "");
                fm.addText("密码", "Password", "");
                fm.addText("数据库名", "Database", "");
                switch (type) {
                    case "SQLite":
                        return this.dialogValue(new WebMeta().put("File", initer.providerName()));
                    case "Oracle":
                        fm.addText("端口", "Port", "1521");
                        fm.addText("表前缀", "Prefix", "").put("tip", "分表设置");
                        fm.title("Oracle连接配置");
                        break;
                    case "MySql":

                        fm.addText("端口", "Port", "3306");
                        fm.addText("表前缀", "Prefix", "").put("tip", "分表设置");
                        fm.title("MySql连接配置");
                        break;
                    case "MSSQL":
                        fm.addText("端口", "Port", "1433");
                        fm.addText("表前缀", "Prefix", "").put("tip", "分表设置");
                        fm.title("SQL Server连接配置");
                        break;
                    default:
                        this.prompt("数据类型错误");
                        break;
                }
                fm.submit("确认安装", request.model() + "." + request.cmd());
                return fm;
            }, "Settings");
            Provider provder = null;

            switch (type) {
                case "SQLite":
                    provder = Provider.create("Database", UMC.Data.Sql.SQLIteDBProvider.class.getName());

                    String fname = "Database/" + initer.providerName() + ".sqlite";
                    ;
                    String filename = Utility.mapPath(Utility.mapPath("~/" + fname));

                    File file = new File(filename);
                    if (file.exists() == false) {
                        File pfile = file.getParentFile();
                        if (pfile.exists() == false) {
                            pfile.mkdirs();
                        }
                    }

                    provder.attributes().put("db", fname);// ["db"] = fname;
                    break;
                case "Oracle":
                    provder = Provider.create("Database", UMC.Data.Sql.OracleDbProvider.class.getName());

                    break;
                case "MySql":
                    provder = Provider.create("Database", UMC.Data.Sql.MySqlDbProvider.class.getName());

                    break;
                case "MSSQL":
                    provder = Provider.create("Database", UMC.Data.Sql.SqlDbProvider.class.getName());

                    break;
                default:
                    this.prompt("数据类型错误");
                    break;
            }
            provder.attributes().put("host", Settings.get("Server"));
            provder.attributes().put("port", Settings.get("Port"));
            provder.attributes().put("database", Settings.get("Database"));
            String Prefix = Settings.get("Prefix");
            String Delimiter = Settings.get("Delimiter");
            if (!Utility.isEmpty(Prefix)) {
                provder.attributes().put("delimiter", Utility.isEmpty(Delimiter) ? "_" : Delimiter);
                provder.attributes().put("prefix", Prefix);
            }
            DbProvider provider = (DbProvider) Utility.createInstance(provder);// .CreateObject(provder) as DbProvider;
            Database factory = Database.instance(provider);// . (provider);
            try {
                factory.open();
                factory.close();

                Provider p = Provider.create(initer.providerName(), provder.type());
                Iterator<Map.Entry<String, String>> set = provder.attributes().entrySet().iterator();
                while (set.hasNext()) {
                    Map.Entry<String, String> entry = set.next();
                    p.attributes().put(entry.getKey(), entry.getValue());
                }
                database.put(p);
                ProviderConfiguration.configuration("database", database);
            } catch (Exception ex) {
                ex.printStackTrace();
                this.prompt("安装异常", ex.getMessage());
            }
        }

        Provider provder = setup.get(initer.name());
        if (provder == null) {
            provder = Provider.create(initer.name(), initer.getClass().getName());
        }
        if (Utility.isEmpty(provder.get("setup"))) {
            if (Utility.isEmpty(initer.providerName())) {
                initer.setup();
            } else {
                initer.setup((DbProvider) Utility.createInstance(database.get(initer.providerName())));
                initer.setup();
            }
            provder.attributes().put("setup", "true");

            setup.put(provder);

            ProviderConfiguration.configuration("setup", setup);

            this.prompt("安装完成", false);

        } else {
            if (Utility.isEmpty(initer.providerName())) {
                initer.upgrade();
            } else {
                initer.upgrade((DbProvider) Utility.createInstance(database.get(initer.providerName())));
                initer.upgrade();
            }
            this.prompt("更新完成", false);
        }

        this.context().send(request.model() + "." + request.cmd(), true);

    }

}
